package NWish.properties.object3ds
{
	import NWish.Misc;
	import NWish.json.Json;
	import NWish.json.OrderDict;
	import NWish.properties.Properties;
	import NWish.properties.custom.CustomProperties;
	
	import NWish.Interface.ILogger;
	
	import away3d.cameras.Camera3D;
	import away3d.containers.ObjectContainer3D;
	import away3d.containers.Scene3D;
	import away3d.core.base.Object3D;
	import away3d.entities.Mesh;
	import away3d.entities.Sprite3D;
	import away3d.lights.*;
	import away3d.primitives.*;

	public class Scene3DProperties extends Properties
	{
		static private var _propertiesTypeMap = [];
		
		var _createObjectList;
		
		public function Scene3DProperties(parent = null, createObjectList = null/*[]*/)
		{
			super(parent);
			
			//
			addPropertieKeys_read('Scene3D',['numChildren']);
			
			addPropertieKeys_save('Scene3D',['numChildren']);

			//
			_createObjectList = createObjectList;
		}
		
		
		override public function get type()
		{
			return Scene3D;
		}
		
		/*override public function newType(scene,dict)
		{
			var s:Scene3D = super.newType(scene,dict);
			s.extra = new Object();
			s.extra.ambientColor = 0x555555;
			return s;
		}*/
		
		override public function toString()
		{
			return "Scene";
		}
		
		static public function addPropertiesType(objType,proType,rename = null)
		{
			_propertiesTypeMap.push({objectType:objType,propertiesType:proType,rename:rename});
		}
		
		override public function propertiesToDict(obj,d:OrderDict,read_only = false,saving = false)
		{
			super.propertiesToDict(obj,d,read_only,saving);
			
			if(read_only)
			{
				var num = obj.numChildren;
				var children:Array = [];
				for(var i = 0; i < num; ++i)
				{
					children.push(obj.getChildAt(i).name);
				}
				d.push(readMark + 'children', children);
			}
			else
			{
				d.push('ambientColor',obj.extra.ambientColor);
			}
		}
		
		override public function dictToProperties(dict,obj,scene:Scene3D,isloading)
		{
			super.dictToProperties(dict,obj,scene,isloading);
			
			var ac = dict['ambientColor'];
			if(obj.extra.ambientColor != ac)
			{
				obj.extra.ambientColor = ac;
				
				function setAmbientColor(o:Object)
				{
					if(o.hasOwnProperty('material'))
					{
						if(o is Mesh)
						{
							var m:Mesh = o as Mesh;
							for each(var sub in m.subMeshes)
							{
								sub.material.ambientColor = ac;
							}
						}
						else
						{
							if(o.material.hasOwnProperty('ambientColor'))
								o.material.ambientColor = ac;
						}
					}
				}
				
				Misc.foreachChildren(obj,setAmbientColor);
			}
		}
		
		
		
		//
		override public function save(obj,toDict:OrderDict,subPropertiesType:Array = null,isChild = false)
		{
			var subDict = super.save(obj,toDict,subPropertiesType);
			
			for (var i = 0; i < obj.numChildren; ++i)
			{
				var c = obj.getChildAt(i);
				
				saveObject3D(c,subDict);
			}
		}
		
		public function saveObject3D(obj,dict)
		{
			var subDict;
			var pts;
			
			for each(var ptm in _propertiesTypeMap)
			{
				var ot = ptm.objectType;
				var pt = ptm.propertiesType;
				if(Misc.isClass(obj, ot))
				{
					if(pt is Function)
					{
						subDict = pt(obj, dict, true);
						if(subDict == null)
							return;
					}
					else
					{
						pts = new pt(null);
						subDict = pts.save(obj, dict, [CustomProperties], true);
						break;
					}
				}
			}
			
			if(pts && pts.saveChildren)
				for (var i = 0; i < obj.numChildren; ++i)
				{
					var c = obj.getChildAt(i);
					
					if(c.extra
					&& c.extra.customProperties
					&& c.extra.customProperties.isSave == false)
					{
						//var __test = 0;
					}
					else
						saveObject3D(c,subDict);
				}
		}
		
		override public function load(dict,obj,scene,subPropertiesType:Array = null)
		{
			super.load(dict,obj,scene,subPropertiesType);
			
			
			loadObject3D(toString(),dict[toString()],scene,true,Properties.priorityMask);//优先读取待遇   '@' 字符的数据
			loadObject3D(toString(),dict[toString()],scene);
		}
		
		public function loadObject3D(key:String,dict,scene,priority = false,priority_mask = Properties.priorityMask)
		{
			//
			if(key == 'Scene')
			{
				//do nothing but read child info
				//ILogger.log('Ignore child type ' + key + ' : ' + dict[key]);
			}
			else
			{
				if(priority == false)
				{
					var pos = key.search(priority_mask);
					if(pos == -1)
						loadObject3D1(key,dict,scene);
				}
				else
				{
					var pos = key.search(priority_mask);
					if(pos != -1)
						loadObject3D1(key,dict,scene);
				}
			}
			
			//
			for(var k in dict)
			{
				var o = dict[k];
				
				/*if(o is int
				|| o is uint
				|| o is String
				|| o is Number
				|| o is Boolean
				|| o is Array
				|| o == null
				|| k.search('direction') != -1
				|| k.search('Material') != -1
				|| k.search('subMeshs') != -1
				|| k.search('Sub Mesh:') != -1)
					continue;*/
				
				if(k.search(':child') != -1)
				{
					loadObject3D(k,o,scene,priority);
				}
			}
		}
		
		private function loadObject3D1(key:String,dict,scene)
		{
			var find = false;
			var createObj;
			
			//
			for each(var ptm in _propertiesTypeMap)
			{
				var ot = ptm.objectType;
				var pt = ptm.propertiesType;
				var rn = ptm.rename;
				
				var otn:String;
				if(rn)
					otn = rn;
				else
				{
					otn = ot;
					otn = otn.replace('[class ','');
					otn = otn.replace(']','');
				}
				
				
				if(key.search(otn) != -1)
				{
					if(pt is Function)
					{
						createObj = pt({otn:dict},null,scene);
						//if(createObj == null)
						//	return;
					}
					else
					{
						var o = {};
						o[otn] = dict;
						createObj = new pt(_app).load
							( o
							, null
							, scene
							, [CustomProperties]);
					}
					
					find = true;
					break;
				}
			}
			
			if(find == false)
				ILogger.log('cannot not read type : ' + key); 
			
			
			if(_createObjectList && createObj)
				_createObjectList.push(createObj);
			//return createObj;
		}
		
		
		public function get createObjectList()
		{
			return _createObjectList;
		}
		
		static public function importScene(json,app,notifyNWEventEnable:Boolean)
		{
			var dict:Object;
			if(json is String)
				dict = Json.decode( json,false );
			else
				dict = json;
			
			
			if(notifyNWEventEnable == false)
				app.notifyNWEventEnable = false;
			//
			var arr = [];
			for (var k:String in dict)
			{
				var sp = new Scene3DProperties(app,arr);
				sp.loadObject3D(k,dict[k], app.away3d.scene);
			}
			
			if(notifyNWEventEnable == false)
				app.notifyNWEventEnable = true;
			
			return arr;
		}
		
	}
}


